<template>
  <div class="border">
    <Toolbar
      class="border-b"
      :editor="editorRef"
      :default-config="setting"
      :mode="mode"
    />
    <Editor
      :model-value="props.modelValue"
      class="overflow-y-hidden"
      :style="{ height: Number.isNaN(height) ? height : `${height}px` }"
      :default-config="setting"
      :mode="mode"
      @on-created="onCreated"
      @update:model-value="onChange"
    />
  </div>
</template>

<script setup lang="ts">

import '@wangeditor/editor/dist/css/style.css' // 引入 css

import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { IDomEditor, IEditorConfig, IToolbarConfig } from '@wangeditor/editor'

/**
 * 富文本编辑器
 *
 * <Editor v-model="xx">
 */
const props = withDefaults(defineProps<{
  modelValue: string
  disabled?: boolean
  height?: number
  setting?: Partial<IToolbarConfig> & Partial<IEditorConfig>
  mode? : string
}>(), {
  disabled: false,
  height: 500,
  mode: 'default',
})

const emits = defineEmits<{
  (event: 'update:modelValue', value: string): void
  (event: 'change', value: string): void
  (event: 'update:uploading', value: boolean): void
}>()

const permission = usePermission()
const uploading = ref(0)

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef<IDomEditor>()

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  editorRef.value?.destroy()
})

function onCreated(editor: IDomEditor) {
  editorRef.value = editor // 记录 editor 实例，重要！
}

const setting = computed<Partial<IToolbarConfig> & Partial<IEditorConfig>>(() => {
  const def: Partial<IEditorConfig> = {
    readOnly: props.disabled,
    placeholder: '请输入内容...',
    MENU_CONF: {
      uploadImage: {
        async customUpload(file: File, insertFn: (string: string, alt: string, href: string) => void) {
          try {
            uploading.value += 1
            emits('update:uploading', true)
            const body = new FormData()
            body.append('file', file)
            const response = await fetch(import.meta.env.VITE_APP_UPLOAD_API, {
              method: 'POST',
              body,
              headers: {
                Authorization: `Bearer ${permission.token}`,
              },
            })
            const res = await response.json()
            if (res.code === 200 || res.code === 0) {
              const url = import.meta.env.VITE_APP_BASE_CDN + (res.fileName || res.data)
              insertFn(url, file.name, url)
              return Promise.resolve()
            }
            return Promise.reject('图片上传失败')
          } catch (e) {
            return Promise.reject('图片上传失败')
          } finally {
            uploading.value -= 1
            if (uploading.value <= 0) {
              emits('update:uploading', false)
            }
          }
        },
      },
    },
  }
  return {
    ...def,
    ...props.setting,
  }
})

const onChange = (value: string) => {
  emits('update:modelValue', value)
  emits('change', value)
}

onBeforeUnmount(() => {
  editorRef.value?.destroy()
})

</script>

<style scoped lang="scss">

</style>

<style lang="scss">
.tox-notification--warning, .tox-statusbar__branding {
  display: none !important;
}
</style>
